package com.whale.cloud.util;

import com.whale.cloud.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author iBo @Description: 时间相关工具
 * @date 2014-8-30 下午10:42:21
 */
public class TimeUtils {

  public static final SimpleDateFormat DATETIME_FORMAT_DAY = new SimpleDateFormat("yyyy-MM-dd");
  public static final SimpleDateFormat DATETIME_FORMAT_DATE =
      new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  public static final SimpleDateFormat DATETIME_FORMAT_DATE_no =
      new SimpleDateFormat("yyyy-MM-dd HH:mm");
  public static final SimpleDateFormat DATETIME_FORMAT_DATE_MS =
      new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
  public static final SimpleDateFormat DATE_FORMAT_DATE = new SimpleDateFormat("yyyy-MM-dd");
  public static final SimpleDateFormat DATE_FORMAT_DATE_NO = new SimpleDateFormat("yyyyMMdd");
  public static final SimpleDateFormat DATETIME_FORMAT_DATE_NO =
      new SimpleDateFormat("yyyyMMddHHmmss");
  public static final SimpleDateFormat DATETIME_FORMAT_DATE_NO_MS =
      new SimpleDateFormat("yyyyMMddHHmmssSSS");
  public static final SimpleDateFormat DATETIME_FORMAT_DATE_NO_MS_S =
      new SimpleDateFormat("yyMMddHHmmssSSS");
  public static final SimpleDateFormat DATETIME_FORMAT_DATE_SNO =
      new SimpleDateFormat("yyMMddHHmmss");
  public static final SimpleDateFormat TIME_FORMAT_DATE_NO = new SimpleDateFormat("ddHHmmss");
  public static final SimpleDateFormat MONTH_FORMAT_DATE = new SimpleDateFormat("yyyy-MM");
  public static final SimpleDateFormat MONTH_FORMAT = new SimpleDateFormat("yyyyMM");
  public static final SimpleDateFormat FORMAT_DATE = new SimpleDateFormat("MMdd");
  public static final SimpleDateFormat FORMAT_MONTH = new SimpleDateFormat("MM");
  public static final SimpleDateFormat FORMAT_YEAR = new SimpleDateFormat("yyyy");

  /**
   * 获取某月第一天
   *
   * @param time 日期时间
   * @return
   * @throws Exception
   */
  public static String monthFirstDay(String time) throws Exception {
    Calendar calendar = Calendar.getInstance();
    // 设置时间,当前时间不用设置
    calendar.setTime(TimeUtils.MONTH_FORMAT.parse(time));
    // 设置日期为本月最大日期
    //		calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
    calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DATE));
    // 打印
    return TimeUtils.DATE_FORMAT_DATE_NO.format(calendar.getTime());
  }

  /**
   * @param date
   * @param dateFormat
   * @return
   */
  public static String formatDateByPattern(Date date, String dateFormat) {
    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
    String formatTimeStr = null;
    if (date != null) {
      formatTimeStr = sdf.format(date);
    }
    return formatTimeStr;
  }

  /**
   * 获取某月最后一天
   *
   * @param time
   * @return
   * @throws Exception
   */
  public static String monthLastDay(String time) throws Exception {
    Calendar calendar = Calendar.getInstance();
    // 设置时间,当前时间不用设置
    calendar.setTime(TimeUtils.MONTH_FORMAT.parse(time));
    // 设置日期为本月最大日期
    calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
    //		calendar.set(Calendar.DATE,calendar.getActualMinimum(Calendar.DATE));
    // 打印
    return TimeUtils.DATE_FORMAT_DATE_NO.format(calendar.getTime());
  }

  /**
   * 根据指定日期 需要减去的天数 获取前一天的新日期
   *
   * @param date 日期 2016-5-17
   * @return 2016-5-16
   */
  public static Date getLastDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.DAY_OF_MONTH, -1);
    date = calendar.getTime();
    return date;
  }

  /**
   * 根据指定日期 需要减去的天数 获取后一天的新日期
   *
   * @param date 日期 2016-5-17
   * @return 2016-5-16
   */
  public static Date getNextDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.DAY_OF_MONTH, 1);
    date = calendar.getTime();
    return date;
  }

  /**
   * 根据指定日期 需要减去的月数 获取减去或添加月数后的新日期
   *
   * @param date 日期 2016-5-17
   * @param i 减去的月数 1
   * @return 2016-4-17
   */
  public static Date getLastDate(Date date, int i) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.add(Calendar.MONTH, i);
    return cal.getTime();
  }

  /**
   * 根据指定日期 需要减去的天数 获取减去或添加天数后的新日期
   *
   * @param date 日期 2016-5-17
   * @param i 减去的天数 7
   * @return 2016-5-10
   */
  public static Date getLastDateByDay(Date date, int i) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.add(Calendar.DAY_OF_MONTH, i);
    return cal.getTime();
  }

  /**
   * long time to string
   *
   * @param timeInMillis
   * @param dateFormat
   * @return
   */
  public static String getTime(long timeInMillis, SimpleDateFormat dateFormat) {
    return dateFormat.format(new Date(timeInMillis));
  }

  /**
   * long time to string, format is {@link #}
   *
   * @param timeInMillis
   * @return
   */
  public static String getTime(long timeInMillis) {
    return getTime(timeInMillis, DATETIME_FORMAT_DATE);
  }

  /**
   * get current time in milliseconds
   *
   * @return
   */
  public static long getCurrentTimeInLong() {
    return System.currentTimeMillis();
  }

  public static int getCurrentYear() {
    Calendar cal = Calendar.getInstance();
    int year = cal.get(Calendar.YEAR);
    return year;
  }

  public static int getCurrentMonth() {
    Calendar cal = Calendar.getInstance();
    int month = cal.get(Calendar.MONTH) + 1;
    return month;
  }

  public static int getCurrentDay() {
    Calendar cal = Calendar.getInstance();
    int day = cal.get(Calendar.DATE);
    return day;
  }

  /**
   * get current time in milliseconds, format is {@link #}
   *
   * @return
   */
  public static String getCurrentTimeInString() {
    return getTime(getCurrentTimeInLong());
  }

  /**
   * get current time in milliseconds
   *
   * @return
   */
  public static String getCurrentTimeInString(SimpleDateFormat dateFormat) {
    return getTime(getCurrentTimeInLong(), dateFormat);
  }

  /**
   * @param :@param firstStr
   * @param :@param secondStr @Title: compareDateTime @Description: 比较日期大小
   */
  public static boolean compareDateTime(
      String firstStr, String secondStr, SimpleDateFormat simpleDateFormat) {
    Date firstDate = null;
    Date secondDate = null;
    try {
      firstDate = simpleDateFormat.parse(firstStr);
      secondDate = simpleDateFormat.parse(secondStr);
    } catch (ParseException e) {
      e.printStackTrace();
    }
    long firstLongTime = firstDate.getTime();
    long secondLongTime = secondDate.getTime();
    if (firstLongTime > secondLongTime) {
      return false;
    } else {
      return true;
    }
  }

  /**
   * 几天前
   *
   * @param beforDay
   * @param simpleDateFormat
   * @return
   */
  public static String getTimeBeforDay(int beforDay, SimpleDateFormat simpleDateFormat) {
    Calendar c = Calendar.getInstance();
    int day = c.get(Calendar.DAY_OF_MONTH) - beforDay;
    c.set(Calendar.DAY_OF_MONTH, day);
    return simpleDateFormat.format(c.getTime());
  }

  /**
   * 某日的几天前
   *
   * @param beforDay
   * @param simpleDateFormat
   * @return
   */
  public static String getTimeBefore(int beforDay, String date, SimpleDateFormat simpleDateFormat)
      throws Exception {
    Date days = simpleDateFormat.parse(date);
    Calendar c = Calendar.getInstance();
    c.setTime(days);
    int day = c.get(Calendar.DAY_OF_MONTH) - beforDay;
    c.set(Calendar.DAY_OF_MONTH, day);
    return simpleDateFormat.format(c.getTime());
  }

  /**
   * 获取两个日期相差天数
   *
   * @param date1
   * @param date2
   * @return
   * @throws ParseException
   */
  public static int calculateDateInDay(
      String date1, String date2, SimpleDateFormat simpleDateFormat) throws ParseException {

    Date now = simpleDateFormat.parse(date1);
    Date date = simpleDateFormat.parse(date2);
    long l = now.getTime() - date.getTime();
    long day = l / (24 * 60 * 60 * 1000);
    return (int) day;
  }

  /**
   * 获取两个日期相差小时数
   *
   * @param date1
   * @param date2
   * @param simpleDateFormat
   * @return
   * @throws ParseException
   */
  public static int calculateDateInHour(
      String date1, String date2, SimpleDateFormat simpleDateFormat) throws ParseException {

    Date now = simpleDateFormat.parse(date1);
    Date date = simpleDateFormat.parse(date2);
    long l = now.getTime() - date.getTime();
    long day = l / (60 * 60 * 1000);
    return (int) day;
  }

  /**
   * 某日所属的周一到周日
   *
   * @param date (yyyy-MM-dd)
   * @return
   * @throws Exception
   */
  public static String getWeek(String date) throws Exception {
    Date time = TimeUtils.DATETIME_FORMAT_DAY.parse(date);
    Calendar cal = Calendar.getInstance();
    cal.setTime(time);
    //判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
    int dayWeek = cal.get(Calendar.DAY_OF_WEEK); //获得当前日期是一个星期的第几天
    if (1 == dayWeek) {
      cal.add(Calendar.DAY_OF_MONTH, -1);
    }
    cal.setFirstDayOfWeek(Calendar.MONDAY); //设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
    int day = cal.get(Calendar.DAY_OF_WEEK); //获得当前日期是一个星期的第几天
    cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day); //根据日历的规则，给当前日期减去星期几与一个星期第一天的差值

    String monday = TimeUtils.DATETIME_FORMAT_DAY.format(cal.getTime());
    cal.add(Calendar.DATE, 1);
    String tuesday = TimeUtils.DATETIME_FORMAT_DAY.format(cal.getTime());
    cal.add(Calendar.DATE, 1);
    String wednesday = TimeUtils.DATETIME_FORMAT_DAY.format(cal.getTime());
    cal.add(Calendar.DATE, 1);
    String thursday = TimeUtils.DATETIME_FORMAT_DAY.format(cal.getTime());
    cal.add(Calendar.DATE, 1);
    String friday = TimeUtils.DATETIME_FORMAT_DAY.format(cal.getTime());
    cal.add(Calendar.DATE, 1);
    String saturday = TimeUtils.DATETIME_FORMAT_DAY.format(cal.getTime());
    cal.add(Calendar.DATE, 1);
    String sunday = TimeUtils.DATETIME_FORMAT_DAY.format(cal.getTime());

    return monday + "," + tuesday + "," + wednesday + "," + thursday + "," + friday + "," + saturday
        + "," + sunday;
  }

  /**
   * 指定日期属于星期几
   *
   * @return
   */
  public static int dayForWeek(String date) throws Exception {

    Date time = TimeUtils.DATETIME_FORMAT_DAY.parse(date);
    Calendar cal = Calendar.getInstance();
    cal.setTime(time);

    int dayForWeek = 0;
    if (cal.get(Calendar.DAY_OF_WEEK) == 1) {
      dayForWeek = 7;
    } else {
      dayForWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
    }

    return dayForWeek;
  }

  public static int dayForWeek_(String pTime) {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Calendar c = Calendar.getInstance();
    c.setFirstDayOfWeek(Calendar.MONDAY);
    try {
      c.setTime(format.parse(pTime));
    } catch (ParseException e) {
      e.printStackTrace();
    }
    int dayForWeek = 0;
    if (c.get(Calendar.DAY_OF_WEEK) == 1) {
      dayForWeek = 7;
    } else {
      dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
    }
    return dayForWeek - 1;
  }

  public static Map getFirstday_Lastday_Month(Date date) {
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.MONTH, -1);
    Date theDate = calendar.getTime();

    //上个月第一天
    GregorianCalendar gcLast = (GregorianCalendar) Calendar.getInstance();
    gcLast.setTime(theDate);
    gcLast.set(Calendar.DAY_OF_MONTH, 1);
    String day_first = df.format(gcLast.getTime());
    StringBuffer str = new StringBuffer().append(day_first).append(" 00:00:00");
    day_first = str.toString();

    //上个月最后一天
    calendar.add(Calendar.MONTH, 2); //加一个月
    calendar.set(Calendar.DATE, 1); //设置为该月第一天
    calendar.add(Calendar.DATE, -1); //再减一天即为上个月最后一天
    String day_last = df.format(calendar.getTime());
    StringBuffer endStr = new StringBuffer().append(day_last);
    day_last = endStr.toString();

    Map map = new HashMap();
    map.put("first", day_first);
    map.put("last", day_last);
    return map;
  }

  //获取该日期所属月份的最后一天日期"2012-05-02"
  public static String getLastDateByDate(String getDate) {
    Map map = null;
    try {
      SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
      String str = getDate;
      Date date = df.parse(str);
      map = getFirstday_Lastday_Month(date);
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }

    return map.get("last").toString();
  }

  private static Date getMonthStart(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    int index = calendar.get(Calendar.DAY_OF_MONTH);
    calendar.add(Calendar.DATE, (1 - index));
    return calendar.getTime();
  }

  private static Date getMonthEnd(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.MONTH, 1);
    int index = calendar.get(Calendar.DAY_OF_MONTH);
    calendar.add(Calendar.DATE, (-index));
    return calendar.getTime();
  }

  //获取该月下的所有日期
  public static List<String> getMonthAllDays(String getDate) {
    List<String> dateList = new ArrayList();
    try {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      String str = getDate;
      Date d = sdf.parse(str);
      // 月初
      //System.out.println("月初" + sdf.format(getMonthStart(d)));
      // 月末
      //System.out.println("月末" + sdf.format(getMonthEnd(d)));

      Date date = getMonthStart(d);
      Date monthEnd = getMonthEnd(d);
      while (!date.after(monthEnd)) {
        dateList.add(sdf.format(date));
        date = getNextDay(date);
      }
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
    return dateList;
  }

  /**
   * Get the Dates between Start Date and End Date.
   *
   * @param p_start Start Date
   * @param p_end End Date
   * @return Dates List
   */
  public static List<String> getDates(Calendar p_start, Calendar p_end) {
    List<String> result = new ArrayList<String>();
    Calendar temp = p_start;
    p_end.add(Calendar.DAY_OF_YEAR, 1);
    while (temp.before(p_end)) {
      result.add(DATE_FORMAT_DATE.format(temp.getTime()));
      temp.add(Calendar.DAY_OF_YEAR, 1);
    }

    return result;
  }

  /**
   * 获取两个日期内的日期
   *
   * @param startDate
   * @param endDate
   * @return
   */
  public static List<String> getDaysByTwoDate(String startDate, String endDate) {
    List<String> dates = new ArrayList();
    try {
      Calendar dayc1 = new GregorianCalendar();
      DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
      Date daystart = df.parse(startDate); //start_date是类似"2013-02-02"的字符串
      dayc1.setTime(daystart);
      Calendar dayc2 = new GregorianCalendar();
      Date dayend = df.parse(endDate); //start_date是类似"2013-02-02"的字符串
      dayc2.setTime(dayend);
      dayc2.add(Calendar.MONTH, 0);
      dates = getDates(dayc1, dayc2);
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
    return dates;
  }

  /**
   * 获取某日期在一年的第几周
   *
   * @param time
   * @return
   * @throws ParseException
   */
  public static int getYearWeek(String time) throws ParseException {
    Calendar ca = Calendar.getInstance();
    SimpleDateFormat dsf = new SimpleDateFormat("yyyyMMdd");
    Date date = dsf.parse(time);

    ca.setTime(date);

    String year = time.substring(0, 4);
    String startDate = year + "0101";
    Date date1 = dsf.parse(startDate);
    Calendar ca1 = Calendar.getInstance();
    ca1.setTime(date1);

    String NextstartDate = (Integer.parseInt(year) + 1) + "0101";
    Date date2 = dsf.parse(NextstartDate);
    Calendar ca2 = Calendar.getInstance();
    ca2.setTime(date2);

    int weekDay = ca1.get(Calendar.DAY_OF_WEEK);
    int nextWeekDay = ca2.get(Calendar.DAY_OF_WEEK);
    int days = ca.get(Calendar.DAY_OF_YEAR);
    int intervalDays = 7 - (weekDay - 2); //今年第一周有几天

    int okDay = weekDay - 1; //今年的1号是星期几

    int koDay = nextWeekDay - 1; //下一年的1号是星期几

    if (intervalDays == 8) {
      intervalDays = 1;
    }

    if (okDay == 0) {
      okDay = 7;
    }

    if (koDay == 0) {
      koDay = 7;
    }

    if (okDay > 4) {
      if (days - intervalDays <= 0) {
        return getYearWeek((Integer.parseInt(year) - 1) + "1231");
      } else {
        if (ca.get(Calendar.WEEK_OF_YEAR) == 1) {
          if (koDay >= 4) {
            return 1;
          } else {
            return (days - intervalDays - 1) / 7 + 1;
          }
        } else {
          return (days - intervalDays - 1) / 7 + 1;
        }
      }

    } else {
      if (days - intervalDays <= 0) {
        return 1;
      } else {
        if (ca.get(Calendar.WEEK_OF_YEAR) == 1) {
          if (koDay >= 4) {
            return (days - intervalDays - 1) / 7 + 2;
          } else {
            return 1;
          }
        } else {
          return (days - intervalDays - 1) / 7 + 2;
        }
      }
    }
  }

  public static String convertTime(String time) throws Exception {
    SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
    Calendar c = new GregorianCalendar();
    c.setFirstDayOfWeek(Calendar.MONDAY);
    c.setMinimalDaysInFirstWeek(7);
    c.setTime(format.parse(time));
    String a_time_Y = String.valueOf(c.get(Calendar.YEAR));
    String a_time_W;
    String a_time_M;

    if (TimeUtils.getYearWeek(time) >= 10) {
      a_time_W = String.valueOf(TimeUtils.getYearWeek(time));
    } else {
      a_time_W = "0" + String.valueOf(TimeUtils.getYearWeek(time));
    }
    if (c.get(Calendar.MONTH) >= 9) {
      a_time_M = String.valueOf(c.get(Calendar.MONTH) + 1);
    } else {
      a_time_M = "0" + String.valueOf(c.get(Calendar.MONTH) + 1);
    }
    String a_time_D = time.substring(6);
    return a_time_Y + "," + a_time_M + "," + a_time_W + "," + a_time_D;
  }
  /**
    判断当前时间是否在指定时间之内
    开始时间为空              false
    结束时间为空              >=开始时间 true
    开始时间结束时间不为空    >=开始时间 <= 结束时间 true
   */
  public static boolean timeRange(String start_time,String end_time) throws Exception{
    long time = System.currentTimeMillis();
    boolean is_ture=false;
    if (StringUtils.isNull(start_time)){
      return is_ture;
    }
    if (StringUtils.isNull(end_time)){
      is_ture= time>=TimeUtils.DATETIME_FORMAT_DATE.parse(start_time).getTime();
      return is_ture;
    }
    is_ture= time>=TimeUtils.DATETIME_FORMAT_DATE.parse(start_time).getTime() && time<=TimeUtils.DATETIME_FORMAT_DATE.parse(end_time).getTime();
    return is_ture;
  }
  // 判断 yyyyMMdd 是否为当天
  public static boolean isTheDay(String day){
    day=day.substring(4);
    String time=TimeUtils.getCurrentTimeInString(TimeUtils.FORMAT_DATE);
    if (day.equals(time)){
      return true;
    }
    return false;
  }
  // 判断 yyyyMMdd 是否为当月
  public static boolean isTheMonth(String day){
    String time=TimeUtils.getCurrentTimeInString(TimeUtils.FORMAT_MONTH);
    day=day.substring(4,6);
    if (day.equals(time)){
      return true;
    }
    return false;
  }
  // 判断 当前年是否大于 day
  public static boolean BTheYear(String day){
    String time=TimeUtils.getCurrentTimeInString(TimeUtils.FORMAT_YEAR);
    if (Integer.parseInt(time)>Integer.parseInt(day)){
        return true;
    }
    return false;
  }
  public static void main(String[] args) throws Exception {

    //        System.out.println();
    ////        String time = TimeUtils.getCurrentTimeInString(TimeUtils.DATETIME_FORMAT_DATE_MS);
    ////
    ////        System.out.println(time);
    ////        System.out.println(TimeUtils.getLongTime(time, TimeUtils.DATETIME_FORMAT_DATE_MS));
    //
    //        System.out.println("lllllll:"+compareDateTime("2016-02-30","2016-04-31",TimeUtils.DATE_FORMAT_DATE));

    /*SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String str = "2016-02-10";
    Date d = sdf.parse(str);
    // 月初
    System.out.println("月初" + sdf.format(getMonthStart(d)));
    // 月末
    System.out.println("月末" + sdf.format(getMonthEnd(d)));

    Date date = getMonthStart(d);
    Date monthEnd = getMonthEnd(d);
    while (!date.after(monthEnd)) {
        System.out.println(sdf.format(date));
        date = getNextDay(date);
    }*/

    /*System.out.println(TimeUtils.compareDateTime("2016-08-04","2016-08-04",TimeUtils.DATE_FORMAT_DATE));*/

    /* List<String> dates = getDaysByTwoDate("2013-02-22","2013-03-15");
    int i = 0;
    while (i < dates.size()){
        System.out.println(dates.get(i));
        i++;
    }*/
    /*String  name = "~!@#$%&*".equals("~!@#$%&*")?"1":"2";
            System.out.println(name);


            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DAY_OF_WEEK, 0);
            int index = calendar.get(Calendar.DAY_OF_WEEK);

            System.out.println(TimeUtils.getDateStr(calendar.getTime(),TimeUtils.DATE_FORMAT_DATE));
             String   timeStap = ""+System.currentTimeMillis();
            timeStap = timeStap.substring(0,10);
            System.out.print(timeStap);
            String  abc = null;
            if(!"".equals(abc) && null != abc){
                abc = "123";
            }

            System.out.println("abc:"+abc);
    */

    //        int i = "1999.01".compareTo("2000.00");
    //        System.out.println("==i==" + i);

  }
}
